package com.zyf.chapter02.behavior.iterator.snapshot.timestamp;

import com.zyf.chapter02.behavior.iterator.snapshot.Iterator;
import com.zyf.chapter02.behavior.iterator.snapshot.List;

/**
 * 利用时间戳实现快照版本<br />
 * 注：未实现扩容，另外，元素删除只是打上一个时间戳标记，实际并未删除
 * </p> 问题：由于不是真正的删除，导致无法支持按照下标快速随机访问了
 * @author yifeng
 */
public class ArrayList<E> implements List<E> {
    private static final int DEFAULT_CAPACITY = 10;

    private int actualSize; // 不包含标记删除元素
    private int totalSize; // 包含标记删除元素

    private Object[] elements;
    private long[] addTimestamps;
    private long[] delTimestamps;

    public ArrayList() {
        this.elements = new Object[DEFAULT_CAPACITY];
        this.addTimestamps = new long[DEFAULT_CAPACITY];
        this.delTimestamps = new long[DEFAULT_CAPACITY];

        actualSize = 0;
        totalSize = 0;
    }

    @Override
    public Iterator iterator() {
        return null;
    }

    @Override
    public int size() {
        return actualSize;
    }

    @Override
    public E get(int index) {
        if (index >= totalSize) {
            throw new IndexOutOfBoundsException();
        }
        return (E) elements[index];
    }

    @Override
    public boolean add(E e) {
        // 元素不是真实删除，所以要存在 total 的位置上
        elements[totalSize] = e;
        addTimestamps[totalSize] = System.currentTimeMillis();
        delTimestamps[totalSize] = Long.MAX_VALUE;
        actualSize++;
        totalSize++;
        return true;
    }

    @Override
    public void remove(E e) {
        for (int i = 0; i < elements.length; i++) {
            if (elements[i].equals(e)) {
                delTimestamps[i] = System.currentTimeMillis();
                actualSize--;
            }
        }
    }

    public long getAddTimestamp(int i) {
        if (i >= totalSize) {
            throw new IndexOutOfBoundsException();
        }

        return addTimestamps[i];
    }

    public long getDelTimestamp(int i) {
        if (i >= totalSize) {
            throw new IndexOutOfBoundsException();
        }

        return delTimestamps[i];
    }

    public int getActualSize() {
        return actualSize;
    }

    public int getTotalSize() {
        return totalSize;
    }
}
